/**  
 * Copyrights@2006, Tianyuan DIC Information Co.,Ltd.
 * 文件名:    TMallPayHandle.java  
 * 描述:   
 * 作者:     kaiyang
 * 版本:    1.0  
 * 创建时间:   2015年5月4日 上午11:57:29  
 *  
 * 修改历史:  
 * 日期                          作者           版本         描述  
 * ------------------------------------------------------------------  
 * 2015年5月4日      kaiyang      1.0        1.0 Version  
 */ 
package com.hp.bon.sgw.wh.channel.handler;

import java.io.IOException;
import java.io.PrintStream;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;

import org.apache.commons.lang.StringEscapeUtils;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.hp.bon.sgw.Constants;
import com.hp.bon.sgw.Constants.MessageType;
import com.hp.bon.sgw.bean.XmlMessage;
import com.hp.bon.sgw.core.BuzProcessorManager;
import com.hp.bon.sgw.core.CallParam;
import com.hp.bon.sgw.core.channel.SoapChannel;
import com.hp.bon.sgw.core.channel.handler.IAsynCallHandler;
import com.hp.bon.sgw.domain.MessageDetail;
import com.hp.bon.sgw.start.SpringContext;
import com.hp.bon.sgw.threads.MessageDetailCacheManager;
import com.hp.bon.sgw.threads.TaskManager;
import com.hp.bon.sgw.wh.Constants.AliParam;
import com.hp.bon.sgw.wh.Constants.IVRParam;
import com.hp.bon.sgw.wh.bean.Recharge;
import com.hp.bon.sgw.wh.bean.TInterfacePassword;
import com.hp.bon.sgw.wh.bean.tmall.WingBalanceQuery;
import com.hp.bon.sgw.wh.channel.RenewChannel;
import com.hp.bon.sgw.wh.service.TMallResponseService;
import com.hp.bon.sgw.wh.service.TYConfigService;
import com.hp.bon.sgw.wh.service.TmallLogDao;
import com.hp.ocs.diameter.message.AVP;
import com.hp.ocs.diameter.message.AVP_Grouped;
import com.hp.ocs.diameter.message.AVP_Integer32;
import com.hp.ocs.diameter.message.AVP_UTF8String;
import com.hp.ocs.diameter.message.Message;

import freemarker.template.Template;

/**  
 * @ClassName: TMallPayHandle   
 * @Description: TODO  
 * @author: kaiyang  
 * @date:2015年5月4日 上午11:57:29     
 */
public class RechargeHandle  implements IAsynCallHandler{
	private static final Logger logger = LoggerFactory.getLogger(RenewChannel.class);
	private PrintStream printStream;
	private TYConfigService tyConfigService;
	private  Map<String, Object> map;
	private String 	IP;
	private String 	responseCode;
	private String 	appCode;
	private String ips;
	private String version;
	private  XmlMessage reqXmlMessage;
    private Template template1 = null;
    public static String temp="";
    public static String ip="";
    public  String password="";
    public  String url="";
    public  WingBalanceQuery wingBalanceQuery;
    public static String validMark="";
    public static String validBalances="";
    public static String queryFlags="";
    public  Map<String, Recharge> rechargeMap= new HashMap<String, Recharge>();
	public Recharge recharge= new Recharge();
	TmallLogDao tmallLogDao=(TmallLogDao)SpringContext.getInstance().getApplicationContext().getBean("tmallLogDao");
	TInterfacePassword tInterfacePassword = tmallLogDao.getTInterfacePassword();
	public RechargeHandle(PrintStream printStream,Map<String, Object> map,XmlMessage reqXmlMessage,String IP,String password,String url,WingBalanceQuery wingBalanceQuery,String appCode,String ips,String version,String responseCode)
	{
		this.printStream = printStream;
		this.map = map;
		this.IP = IP;
		this.appCode = appCode;
		this.ips = ips;
		this.version = version;
		this.reqXmlMessage = reqXmlMessage;
		this.password = password;
		this.url = url;
		this.responseCode = responseCode;
		this.wingBalanceQuery =	wingBalanceQuery;
	}
	
	@Override
	public int getProtocolType() {
		return 0;
	}
  
	@Override
	public void onCallResult(CallParam callParam) {
		logger.info("onCallResultonCallResult");
		long receiveTime = System.currentTimeMillis();
		XmlMessage ack = null;
		Object response = null;
		if (callParam.getResponse() != null) {
			response = callParam.getResponse();
		} else if (callParam.getRecvResponse() != null) {
			response = callParam.getRecvResponse();
		}
		
		if (response == null) {
			logger.info("response == null");
			ack = SoapChannel.createERRAnwser(
					callParam.getSessionId(),
					callParam.getRetCode() == 3002 ? 11202 : callParam
							.getRetCode(), callParam.getResultMsg());
		} else {
			logger.info("response:feikong");	
			if (response instanceof Message) {// CCA -> XML
				logger.warn("CCA -> XML");	
				ack = BuzProcessorManager.getInstance().convertMessageToAck(
						callParam);
			} else if (response instanceof XmlMessage) {
				logger.info("response instanceof XmlMessage");	
				ack = (XmlMessage) response;
			} else {
				logger.info("unknown response type:"
						+ callParam.getResponse().getClass().getName());
			}
		}
		try {
			String respXML = convertResponseString((Message)response,callParam.getServiceResultCode(),callParam.getSessionId());
			byte[] resp = respXML.getBytes("GBK");
			logger.info("===========respXML之后===============");
			logger.info("===========responseCode==============="+responseCode);
			if(!temp.equals("0")&&!temp.equals("")){
				logger.info("==========temp判断============"+temp+"==");
				Element serviceInformationRecharge = DocumentHelper
						.createElement("Service_Information");
				Element elementRe = serviceInformationRecharge
						.addElement("Result");
				elementRe.setText(temp);
				temp="";
				elementRe = serviceInformationRecharge.addElement("RESPONSECODE");
				elementRe.setText("");
				elementRe = serviceInformationRecharge.addElement("RESPONSECONTENT");
				elementRe.setText("");
				elementRe = serviceInformationRecharge.addElement("CURRDATE");
				elementRe.setText("");
				elementRe = serviceInformationRecharge.addElement("BESTPAYBALANCE");
				elementRe.setText("");
				elementRe = serviceInformationRecharge.addElement("TELBALANCE");
				elementRe.setText("");
				elementRe = serviceInformationRecharge.addElement("TOTALBALANCE");
				elementRe.setText("");
				elementRe = serviceInformationRecharge.addElement("ISBESTPAYACCT");
				elementRe.setText("");
				
//				recharge.setMark("1");
//				AliParam.setTemp("1");//失败或者异常
//				rechargeMap.put(callParam.getSessionId(), recharge);
//				AliParam.setRechargeMap(rechargeMap);
				XmlMessage ack1 = new XmlMessage(true);
				ack1.setMID(callParam.getSessionId());
				ack1.setREPTAG(0);
				ack1.setRTT(String.valueOf(receiveTime));
				ack1.setSIG(null);
				ack1.setRC("0");
				ack1.setDS("SUCCESS");
				ack1.setDATA(serviceInformationRecharge.asXML());
				String respXMLa = convertResponseString(ack1);
				logger.info(respXMLa);
				byte[] resps = respXMLa.getBytes("UTF-8");
				ack1.setLength(resps.length);
				ack1.setMsgTime(System.currentTimeMillis());
				printStream.write(resps);
				printStream.close();
			}else 	if(queryFlags.equals("0")){
				logger.info("=======================queryFlags000000=========");
				
				Element serviceInformation1 = DocumentHelper.createElement("Service_Information");
					Element element1 = serviceInformation1.addElement("BillQuery_Type");
					element1.setText("2");
					element1 = serviceInformation1.addElement("Destination_Account");
					element1.setText(map.get("ACCOUNTID").toString());
					element1 = serviceInformation1.addElement("Area_Code");
					element1.setText(map.get("Area_Code").toString());
					XmlMessage req1 = new XmlMessage(true);
					req1.setIp(IP);
					req1.setMsgTime(receiveTime);
					req1.setMID(reqXmlMessage.getMID()+"A");
					req1.setUID(reqXmlMessage.getUID());
					req1.setSCID("QryBalOwe.Bal@027.ctnbc-bon.net");
					req1.setSIG(null);
					req1.setREPTAG(0);
					req1.setDATA(serviceInformation1.asXML());
					req1.setDataElement(serviceInformation1);
					logger.info("=======================queryFlags000000========="+queryFlags);
					BalanceHandle balanceHandle = new BalanceHandle(printStream,queryFlags);
					queryFlags="";
					CallParam callParam1 = new CallParam(req1.getMID(), req1.getSCID(),req1, req1.getUID(), balanceHandle);
					BuzProcessorManager.getInstance().processRequest(callParam1);
			}else if(queryFlags.equals("1")){
				logger.info("=======================queryFlags111111111111111=========");
				
				Element serviceInformation1 = DocumentHelper.createElement("Service_Information");
					Element element1 = serviceInformation1.addElement("BillQuery_Type");
					element1.setText("2");
					element1 = serviceInformation1.addElement("Destination_Account");
					element1.setText(map.get("ACCOUNTID").toString());
					element1 = serviceInformation1.addElement("Area_Code");
					element1.setText(map.get("Area_Code").toString());
					XmlMessage req1 = new XmlMessage(true);
					req1.setIp(IP);
					req1.setMsgTime(receiveTime);
					req1.setMID(reqXmlMessage.getMID()+"A");
					req1.setUID(reqXmlMessage.getUID());
					req1.setSCID("QryBalOwe.Bal@027.ctnbc-bon.net");
					req1.setSIG(null);
					req1.setREPTAG(0);
					req1.setDATA(serviceInformation1.asXML());
					req1.setDataElement(serviceInformation1);
					QryHandle qryHandle = new QryHandle(printStream,queryFlags, password, url, wingBalanceQuery,reqXmlMessage,appCode,ips,version);
					queryFlags="";
					CallParam callParam1 = new CallParam(req1.getMID(), req1.getSCID(),req1, req1.getUID(), qryHandle);
					BuzProcessorManager.getInstance().processRequest(callParam1);
			}else if(responseCode.equals("")){
				logger.info("=======================responseCode00000=========");
				
				Element serviceInformationRecharge = DocumentHelper
						.createElement("Service_Information");
				Element elementRe = serviceInformationRecharge
						.addElement("Result");
				elementRe.setText("0");
				elementRe = serviceInformationRecharge.addElement("RESPONSECODE");
				elementRe.setText("");
				elementRe = serviceInformationRecharge.addElement("RESPONSECONTENT");
				elementRe.setText("");
				elementRe = serviceInformationRecharge.addElement("CURRDATE");
				elementRe.setText("");
				elementRe = serviceInformationRecharge.addElement("BESTPAYBALANCE");
				elementRe.setText("");
				elementRe = serviceInformationRecharge.addElement("TELBALANCE");
				elementRe.setText("");
				elementRe = serviceInformationRecharge.addElement("TOTALBALANCE");
				elementRe.setText("");
				elementRe = serviceInformationRecharge.addElement("ISBESTPAYACCT");
				elementRe.setText("");
				
				XmlMessage ack1 = new XmlMessage(true);
				ack1.setMID(callParam.getSessionId());
				ack1.setREPTAG(0);
				ack1.setRTT(String.valueOf(receiveTime));
				ack1.setSIG(null);
				ack1.setRC("0");
				ack1.setDS("SUCCESS");
				ack1.setDATA(serviceInformationRecharge.asXML());
				String respXMLa = convertResponseString(ack1);
				logger.info(respXMLa);
				byte[] resps = respXMLa.getBytes("UTF-8");
				ack1.setLength(resps.length);
				ack1.setMsgTime(System.currentTimeMillis());
				printStream.write(resps);
				printStream.close();
				
				
			}
		
		

			callParam.setResponse(ack);
			
			if (callParam.getRetCode() == Constants.ResultCode.SUCCESS) {// 成功的消息，请求应答入库
				logger.info("callParam.getRetCode() ==" + callParam.getRetCode());
				MessageDetail detail = new MessageDetail();
				detail.setBusinessCallId(callParam.getBussinessCallId());
				logger.info("callParam.getBussinessCallId()== " + callParam.getBussinessCallId());
				detail.setSessionId(callParam.getSessionId());
				logger.info("callParam.getSessionId() ==" + callParam.getSessionId());
				detail.setServiceContextId(callParam.getServiceContextId());
				logger.info("callParam.getServiceContextId() ==" + callParam.getServiceContextId());
				detail.setMessageType(MessageType.WSA);
				detail.setDetails(ack.getDATA());
				logger.info("ack.getDATA()== " + ack.getDATA());
				detail.setMsgTime(new Date(ack.getMsgTime()));
				detail.setOpType("send");
				detail.setHostId(callParam.getUserName());
				MessageDetailCacheManager.getInstance().add(detail);
			}
			TaskManager.taskProcess(callParam);
			logger.info("http response(Recharge)aa " + respXML);
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private String convertResponseString(Message answer, int serviceResultCode,String sessionId)
	{
		
		String response = "";	    	
		Map<String,String> data = new HashMap<String, String>();
	
		 if (serviceResultCode == 0)   
		{
			try{
			    //service_infomation
			    AVP avp = answer.find(Constants.DIAMETER_AVP_SERVICE_INFOMATION,Constants.DIAMETER_VENDOR_3GPP);
			    AVP_Grouped avpServiceInfomation = new AVP_Grouped(avp);
			    //Bill_Serial_Nbr
			    AVP queryFlagAvp = avpServiceInfomation.find(5087,Constants.DIAMETER_VENDOR_CT);
			    if (queryFlagAvp != null){
			    	int  queryFlag= new AVP_Integer32(queryFlagAvp).queryValue();
			    	queryFlags=String.valueOf(queryFlag);
			    	AliParam.setQueryFlag(String.valueOf(queryFlag));
			    	data.put("queryFlag",String.valueOf(queryFlag));
			    }
//			    AVP validBalanceAvp = avpServiceInfomation.find(80118,Constants.DIAMETER_VENDOR_CT);
//			    if (validBalanceAvp != null){
////				    	queryFlag = new AVP_UTF8String(queryFlagAvp).queryValue();
//				    	int  validBalance= new AVP_Integer32(validBalanceAvp).queryValue();
//				    	validMark="1";
//				    	validBalances=String.valueOf(validBalance);
//				    	AliParam.setValidBalance(String.valueOf(validBalance));
//				    }
			}catch(Exception e){
//				data.put("coopOrderNo","");
//				data.put("coopOrderStatus",TMallChannel.STATUS_FAIL);
//				data.put("coopOrderSnap","ReCharge");
//				data.put("coopOrderSuccessTime","");
//				data.put("failedCode","0503");
//				data.put("failedReason","");
				e.printStackTrace();
			}
//			data.put("coopOrderNo",billSerialNbr);
//			data.put("coopOrderStatus",TMallChannel.STATUS_SUCCESS);
//			data.put("coopOrderSnap","ReCharge");
//			data.put("coopOrderSuccessTime",operTime);
//			data.put("failedCode", "");
//			data.put("failedReason","");
		}
		else   //充值失败
		{
		    logger.info("设置异常1"+serviceResultCode);
			temp=String.valueOf(serviceResultCode);
		    logger.info("设置异常2"+serviceResultCode);
//			recharge.setServiceResultCode(String.valueOf(serviceResultCode));
		
		}
//		TreeMap<String,String> paraMap = new TreeMap<String, String>();
//		String coopOrderNo = data.get("coopOrderNo");
//		String status = data.get("coopOrderStatus"); 
//		paraMap.put("coopOrderNo", coopOrderNo);
//		paraMap.put("coopOrderStatus", status);
//		if (status != null && (status.equals(TMallChannel.STATUS_SUCCESS)||status.equals(TMallChannel.CANCEL)||status.equals(TMallChannel.STATUS_FAIL)))
//		{
//			if (status.equals(TMallChannel.STATUS_SUCCESS))
//			{
//				String coopOrderSnap = data.get("coopOrderSnap");
//				String coopOrderSuccessTime = data.get("coopOrderSuccessTime");
//				paraMap.put("coopOrderSnap", coopOrderSnap);
//				paraMap.put("coopOrderSuccessTime", coopOrderSuccessTime);
//			}
//			else if (status.equals(TMallChannel.CANCEL) || status.equals(TMallChannel.STATUS_FAIL))
//			{
//				String failedCode = data.get("failedCode");
//				paraMap.put("failedCode",failedCode);
//				paraMap.put("failedReason", failedCode);
//			}
//			String source = "";
//			for(Entry<String,String> entry:paraMap.entrySet())
//			{
//				source += entry.getKey()+entry.getValue();
//			}
//			String sign = SignUtilsImpl.getTmallSign(source);
//			paraMap.put("sign",sign);
//		}
		
	
		response = getResponse1(data);;
		return response;
	}
	public String getResponse1(Map<String, String> data)
	{  
		logger.info("============getResponse1=======");
	    String context = "";
	    if (template1 != null)
	    {
	      StringWriter writer = new StringWriter();
	      try {
	        template1.process(data, writer);
	      } catch (Exception e) {
	    	  logger.error("TMallResponseService getResponse error, msg = {}", e.getMessage());
	        e.printStackTrace();
	      }
	      context = writer.toString();
	    }
	    logger.info("response = {}",context);
	    return context;
	   
	}
	protected String convertResponseString(XmlMessage ack) {
		String orinData = ack.getDATA();
		String dataStr = (orinData == null || orinData.isEmpty()) ? orinData
				: "<![CDATA[" + orinData + "]]>";
		String errMsg = ack.getDS();
		errMsg = (errMsg != null) && (errMsg.indexOf('&') == -1)
				&& (errMsg.indexOf('>') == -1) && (errMsg.indexOf('<') == -1) ? errMsg
				: StringEscapeUtils.escapeXml(errMsg);
		// String respXML__ =
		// "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\"><SOAP-ENV:Header/><SOAP-ENV:Body><ns3:SgwQueryAck xmlns:ns3=\"http://www.chinatelecom.cn/SGW/SOAP\"><MID>"
		// + ack.getMID() + "</MID><REPTAG>0</REPTAG><RTT>" + ack.getRTT() +
		// "</RTT><SIG>"
		// + ack.getSIG() + "</SIG><RC>" + ack.getRC() + "</RC><DS>" + errMsg +
		// "</DS><DATA>" + dataStr +
		// "</DATA></ns3:SgwQueryAck></SOAP-ENV:Body></SOAP-ENV:Envelope>";
		StringBuilder respXML = new StringBuilder();
		respXML.append("<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\"><SOAP-ENV:Header/><SOAP-ENV:Body><ns3:SgwQueryAck xmlns:ns3=\"http://www.chinatelecom.cn/SGW/SOAP\"><MID>");
		respXML.append(ack.getMID());
		respXML.append("</MID><REPTAG>0</REPTAG><RTT>");
		respXML.append(ack.getRTT());
		respXML.append("</RTT><SIG>");
		respXML.append(ack.getSIG());
		respXML.append("</SIG><RC>");
		respXML.append(ack.getRC());
		respXML.append("</RC><DS>");
		respXML.append(errMsg);
		respXML.append("</DS>");
		// //增加unified info
		// if(ack instanceof UnifiedXmlMessage && ack.isUnified()){
		// UnifiedXmlMessage uxmlMsg = (UnifiedXmlMessage)ack;
		// if(!uxmlMsg.getInfoElements().isEmpty()){
		// respXML.append("<INFO>");
		// for(Element infoEle : uxmlMsg.getInfoElements()){
		// String infoData = infoEle.asXML();
		// respXML.append("<![CDATA[");
		// respXML.append(infoData);
		// respXML.append("]]>");
		// }
		// respXML.append("</INFO>");
		// }
		// }
		//
		// //新SOAP请求的新报文转化为老SR、DCC成功后，返回的新SOAP ACK内加入三个AVP组 XML信息
		// if(ack.getInfo()!=null&&!"".equals(ack.getInfo())){
		// respXML.append(ack.getInfo());
		// }
		respXML.append("<DATA>");
		respXML.append(dataStr);
		respXML.append("</DATA></ns3:SgwQueryAck></SOAP-ENV:Body></SOAP-ENV:Envelope>");
		return respXML.toString();
	}
	
}
